#include "StdAfx.h"
#include ".\activemanager.h"

int SortManager( ActiveMgr* t1, ActiveMgr* t2 )
{
	if( t1->dwLastDate == t2->dwLastDate )
		return 0;

	if( t1->dwLastDate > t2->dwLastDate )
		return 1;
	else
		return 0;

	return 1;
}

CActiveManager::CActiveManager(void)
{
	m_bLoaded = FALSE;
}

CActiveManager::~CActiveManager(void)
{
	if( m_bLoaded )
	{
		RemoveOutdated( );

		//Save( );

        	Clear( );

	}
	   
}

void CActiveManager::Clear(void)
{
	map<DWORD, ActiveMgr*>::iterator it;
	for (it = m_mapActveMgr.begin(); it != m_mapActveMgr.end(); ++it )
	{
		delete (*it).second;
	}

	m_mapActveMgr.clear();
}

BOOL CActiveManager::LogManager(DWORD id, DWORD ip, LPCTSTR lpszLocation, LPCTSTR lpszUserAgent, LPCTSTR lpszVersion, OSVERSIONINFOW* lpOS )
{
	map<DWORD, ActiveMgr*>::iterator it;
	ActiveMgr* lpManager = NULL;

	if( !m_bLoaded )
	{
		//Load( );
		m_bLoaded = TRUE;
	}

	it = m_mapActveMgr.find( id );
	if( it != m_mapActveMgr.end() )
	{
		lpManager = (*it).second;		
	}
	else
	{
		lpManager = new ActiveMgr;
		memset( lpManager, 0, sizeof(ActiveMgr) );
		lpManager->dwFirstDate = (DWORD)time(NULL);

		m_mapActveMgr[ id ] = lpManager;
	}

	lpManager->dwLastDate = (DWORD)time(NULL);
	lpManager->id = id;
	lpManager->ip = ip;

	if( lpszLocation )
	{
		memset( lpManager->szLocation, 0, KTV_ACTIVE_MGR_LOCATION_LENGTH*sizeof(WCHAR) );
		wcsncpy( lpManager->szLocation, lpszLocation, min( (KTV_ACTIVE_MGR_LOCATION_LENGTH-1), wcslen(lpszLocation) ) );
	}	

	if( lpszUserAgent )
	{
		memset( lpManager->szUserAgent, 0, KTV_ACTIVE_MGR_BROWSER_LENGTH*sizeof(WCHAR) );
		wcsncpy( lpManager->szUserAgent, lpszUserAgent, min( (KTV_ACTIVE_MGR_BROWSER_LENGTH-1), wcslen(lpszUserAgent) ) );
	}

	if( lpszVersion )
	{
		memset( lpManager->szVersion, 0, KTV_ACTIVE_MGR_VERSION_LENGTH*sizeof(WCHAR) );
		wcsncpy( lpManager->szVersion, lpszVersion, min( (KTV_ACTIVE_MGR_VERSION_LENGTH-1), wcslen(lpszVersion) ) );
	}

	
	if( lpOS )
		memcpy( &(lpManager->osv), lpOS, sizeof(OSVERSIONINFOW) );
	
	RemoveOutdated( );
	
	return TRUE;
}

map<DWORD, ActiveMgr*>* CActiveManager::GetValuePtr(void)
{
	if( !m_bLoaded )
	{
		//Load( );
		m_bLoaded = TRUE;
	}

	return &m_mapActveMgr;
}

BOOL CActiveManager::Load(void)
{
	WCHAR szFilePath[MAX_PATH] = {0};
	wsprintf( szFilePath, L"%s\\SYSTEM\\ACTIVEMGR.DAT", global.GetWorkingDir() );
	CFile cf;

	DatCopyright cp = {0};
	DWORD  dwIndex = 0;
	DWORD  dwNow = (DWORD)time(NULL);
	

	m_bLoaded = TRUE;
	m_bChanged = FALSE;

	if( !cf.Open( szFilePath, CFile::modeRead|CFile::shareDenyNone ) )
		return FALSE;

	cf.Read( &cp, sizeof(cp) );

	for ( dwIndex = 0; dwIndex < cp.dwRecordCount; dwIndex++ )
	{
		ActiveMgr am = {0};
		UINT nBytes = cf.Read( &am, sizeof(am) );

		if( nBytes != sizeof(am) )
			break;

		if( dwNow > am.dwLastDate + KTV_ACTIVE_MGR_OUTDATE )
			continue;

		if( m_mapActveMgr.find( am.id ) == m_mapActveMgr.end() )
		{
			ActiveMgr* lpMgr = new ActiveMgr;
			memset( lpMgr, 0, sizeof(ActiveMgr) );
			memcpy( lpMgr, &am, sizeof(ActiveMgr) );

			m_mapActveMgr[ lpMgr->id ] = lpMgr;
		}
	}
	

	cf.Close( );

	return TRUE;
}

BOOL CActiveManager :: Save(void)
{

	WCHAR szFilePath[MAX_PATH] = {0};
	wsprintf( szFilePath, L"%s\\SYSTEM\\ACTIVEMGR.DAT", global.GetWorkingDir() );
	CFile cf;

	m_bChanged = TRUE;

	

	if( m_mapActveMgr.empty() )
	{
		//DeleteFile( szFilePath );
		return 0;
	}

	DatCopyright cp = {0};
	sprintf( cp.szCopyRight, "SYSDKTV" );
	cp.dwFileSize = sizeof(DatCopyright) + m_mapActveMgr.size()*sizeof(ActiveMgr);
	cp.dwRecordCount = m_mapActveMgr.size();
	cp.dwCreatedDate = (DWORD)time(NULL);

	if( cf.Open( szFilePath, CFile::modeWrite|CFile::modeCreate) )
	{
		cf.Write( &cp, sizeof(cp) );

		map<DWORD, ActiveMgr*>::iterator it;
		for (it = m_mapActveMgr.begin(); it != m_mapActveMgr.end(); ++it )
		{		
			cf.Write((*it).second, sizeof(ActiveMgr) );			
		}

		cf.Close( );
	}

	return TRUE;
}


void CActiveManager::RemoveOutdated(void)
{

	DWORD  dwNow = (DWORD)time(NULL);
	map<DWORD, ActiveMgr*>::iterator it;
	for (it = m_mapActveMgr.begin(); it != m_mapActveMgr.end(); )
	{
		if( dwNow >= (*it).second->dwLastDate + KTV_ACTIVE_MGR_OUTDATE )
		{
			if( (*it).second )
				delete (*it).second;

			m_mapActveMgr.erase( it++ );
		}
		else
		{
			++it;
		}		
	}

}